<?php
include_once '../InfoManager/InfoAuto.php';
include_once '../InfoManager/InfoRoute.php';
include_once '../InfoManager/InfoZtl.php';
include_once '../Model/GateZtl.php';
include_once '../Model/GPS.php';
include_once '../Model/TrafficGPS.php';
include_once '../Utility/AutoUtils.php';
include_once '../AtacCommunicator/ACtraveltime.php';
/*
 * Created on 08/mag/2011
 *	by Claudio Rauso
 *
 */
 
 header ("content-type: text/xml");

 echo '<?xml version="1.0" encoding="UTF-8"?>';
 echo '<traveltime>';
 if((isset($_GET["lat"])) && (isset($_GET["lon"])) && (isset($_GET["dst"]))) {

	$ch = curl_init();
 	$url = InfoAuto::new_URL_google($_GET["lat"], $_GET["lon"], $_GET["dst"]);
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_HEADER, 0);
	// l'opzione seguente fa in modo che il risultato della richiesta sia ritornato da curl_exec e
	// non stampato direttamente
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_TIMEOUT, 30);

	$data = curl_exec($ch);
 	curl_close($ch);
 
 	// creo il documento XML da elaborare
 	$xml = new SimpleXMLElement($data);
 	
 	// stampa informazioni su partenza e arrivo
 	AutoUtils::print_ends($xml->route->leg);
 	
 	// recupera alcuni dati utili
 	$step = count($xml->route->leg->step);
 	$traveltime = $xml->route->leg->duration->value;
 	$itinerari = InfoRoute::get_itinerari();
 	//$segnalazioni = InfoRoute::get_segnalazioni();
 	// inizializza alcune variabili di supporto
 	$db = count($itinerari);
 	$atactime = 0;
 	$sostituiti = 0;
 	$old_link = -1;
 	$waypoint = array();
 	$descrizioni = array();
 	$sost = array();
 	$flag = false;
 	$disponibile = true;
 	$ac = new ACtraveltime;

 	// seleziona le informazioni da inviare al client
 	for($i = 0; $i < $step; $i++) {
 		
 		$one = $xml->route->leg->step[$i];
		$lat = floatval($one->start_location->lat);
		$lon = floatval($one->start_location->lng);
		$onegps = new GPS($lat, $lon);
		array_push($waypoint, $onegps);
		array_push($descrizioni, $xml->route->leg->step[$i]->html_instructions);
 	
 		echo '<step>';
		// indicazioni sulle manovre da compiere e sulle distanze parziali
		AutoUtils::print_instructions($xml->route->leg->step[$i]->html_instructions);
		AutoUtils::print_distance($xml->route->leg->step[$i]->distance->text, true);
			
		// prova a sostituire uno o pi� step google con itinerari atac
		if($disponibile) {
			if($sostituiti == 0) {
				// verifica se uno dei punti presenti nel database dei nodi atac � vicino al punto
				// di inizio dello step
				$x = AutoUtils::get_atac($onegps, $itinerari, $db);
		
				// -1 � il valore ritornato nel caso in cui non ci siano nodi atac vicini
				if($x != -1) {
					
					// controlla tutti i nodi raggiungibili dal nodo trovato
					$raggiungibili = InfoRoute::get_archi($itinerari[$x]->id);
							
					$y = AutoUtils::get_reachable($xml->route->leg, $raggiungibili, $itinerari, $i, $step);
				
					// anche in questo caso -1 � il codice di errore
					if($y != -1) {
						
						try {
							// se � stata gi� effettuata una sostituzione e il tratto � lo stesso
							// non vengono scaricati nuovamente i dati atac
							if($raggiungibili[$y[0][0]][2] != $old_link) {				
								$text = $ac->newConnectToAtac($raggiungibili[$y[0][0]][2]);
								//$text = $ac->connectToAtac($raggiungibili[$y[0][0]][2]);
								$old_link = $raggiungibili[$y[0][0]][2];
							}
							$id_to = $raggiungibili[$y[0][0]][1];
												
							$atac_to = $itinerari[$id_to - 1];
							
							//echo "itinerario: ".$itinerari[$x]->itinerario." atac: ".$atac_to->itinerario;
							$atactime = $ac->newParser($text, $itinerari[$x]->itinerario, $atac_to->itinerario);
						} catch (CommunicationException $e) {
							// il servizio atacmobile non � in funzione: non effettua pi� controlli
							if(strcmp($e->getMessage(), "ACtraveltime: No Response from ATAC") == 0)
 								$disponibile = false;
							
							// se si tratta solo di un errore sulla singola richiesta, lascia la
							// variabile d'appoggio a true
							$atactime = 0;	
						}
		
						// se atac fornisce il tempo per l'itinerario, allora effettua l'aggiornamento
						// del tempo di percorrenza
						if($atactime[0] != 0) {

							$traveltime -= $y[0][1];
							$traveltime += $atactime[0] * 60;
										
							if(isset($lat_to, $lon_to) && $lat == $lat_to && $lon == $lon_to) {
								// l'inizio di questo tratto coincide con la fine del precedente tratto monitorato
								$aux = array_pop($sost);
								$onegps = new TrafficGPS($lat, $lon, $atactime[1], $aux->get_end_condition());
							
							} else {
								// un tratto separato dal precedente tratto monitorato
								$onegps = new TrafficGPS($lat, $lon, $atactime[1], null);
							}						
							// aggiunge la fine del tratto
							$oneto = $xml->route->leg->step[$i + $y[0][2] - 1]; 
							$lat_to = floatval($oneto->end_location->lat);
							$lon_to = floatval($oneto->end_location->lng);
							array_push($sost, $onegps, new TrafficGPS($lat_to, $lon_to, null, $atactime[1]));
							$flag = true;
		
						} else {
							// cominciamo a verificare il passaggio per una via...
							// TODO inserire qui la gestione delle segnalazioni
							// traveltime -= tempo_step
							// traveltimr += funzione che calcola tempo in base a segnalazione
							// inserire i TrafficGPS
							// TODO guarda all'interno della funzione
							$endgps = new GPS($xml->route->leg->step[$i + 1]->start_location->lat, $xml->route->leg->step[$i + 1]->start_location->lng);
							print_r(InfoAuto::isBetween($segnalazioni, $descrizioni[$i], $onegps, $endgps, $one->distance->value));
								
						}
						// tramite questa variabile sappiamo quanti step google sono stati sostituiti
						// e quindi quando controllare nuovamente se c'è possibilità di effettuare sostituzioni
						// TODO aggiungere informazioni per mostrare condizioni traffico anche nella vista testuale dell'app
						$sostituiti = $y[0][2];
					} 
		
 				}
 			
			}
		
		} else {
			
			$endgps = new GPS($xml->route->leg->step[$i + 1]->start_location->lat, $xml->route->leg->step[$i + 1]->start_location->lng);
			print_r(InfoAuto::isBetween($segnalazioni, $descrizioni[$i], $onegps, $endgps, $one->distance->value));
			
		}
		
		echo '</step>';

 		// un altro step � stato analizzato, uno step in meno
 		// per ricominciare i tentativi di sostituzione
 		if($sostituiti > 0)
 			$sostituiti--;
 		
 	}
		 
	// informazioni su distanza e tempo totali
 	AutoUtils::print_distance($xml->route->leg->distance->text, false);
	AutoUtils::print_time($traveltime);
 	
	/*
 	 * trova e visualizza i varchi ZTL presenti sul percorso (quando sar� compreso nell'app)
 	
 	$arrayVarchi = InfoZtl::getGates();
 	$ztl = InfoAuto::FindTheGate($arrayVarchi, $waypoint, $descrizioni); 
 	if($ztl != null) {
 		
 		$n = count($ztl); 
 		echo '<ZTL>';
 			
 		for($i = 0; $i < $n; $i++)
 			echo $ztl[$i]->toXML(EXTENDED_MODE);
 			
 		echo '</ZTL>';
 		
 	}
 	*/

 	// decodifica dei geopoint per disegnare il tracciato sulla mappa
 	// visualizzata dal telefono
 	$geopoint = AutoUtils::decodePolylineToArray($xml->route->overview_polyline->points);
 	$n = count($geopoint);
 	// verifica quali GeoPoint sono interessati dalle sostituzioni effettuate
 	$sost = AutoUtils::approximate_geopoint($geopoint, $n, $sost);
 	
 	for($i = 0; $i < $n; $i++) {
 
 		echo '<geopoint>';	
 		$lat = floatval($geopoint[$i][0]);
		$lon = floatval($geopoint[$i][1]);
		echo "<lat>$lat</lat>";
		echo "<lon>$lon</lon>";
		
		// stampa di eventuali tag riguardanti la condizione del traffico
		if($flag)
			AutoUtils::traffic_tag($sost, $i);
		
 		echo '</geopoint>';
 		
 	}

 }
echo '</traveltime>';
?>
